import { Injectable } from '@nestjs/common';
import { UpdateOssDto } from './dto/update-oss.dto';
import * as fs from 'fs';
import * as uuid from 'uuid';
import path from 'path';
import { ConfigService } from '@nestjs/config';
import { ResultData } from '@/common/utils/result';
import { formatBytes } from '@/common/utils/common.util';
import dayjs from 'dayjs';

@Injectable()
export class OssService {
    private readonly productLocation = process.cwd();

    constructor(
        private readonly config: ConfigService,
        // @InjectRepository(Oss)
        // private readonly ossRepository: Repository<Oss>
    ) {
    }

    async create(file: any, business: string, folderPath: string) {
        // 创建文件夹
        const filePath = path.join(this.productLocation, `${this.config.get<string>('FILE_LOCATION')}`, folderPath);
        if (!fs.existsSync(filePath)) fs.mkdirSync(filePath, { recursive: true });

        // 获取原始文件名和扩展名
        const originalFileName = file.filename; // 原始文件名（包含扩展名）
        const fileExt = originalFileName.split('.').pop()?.toLowerCase() || '';

        // 构建原始文件的完整路径（用于检查是否存在同名文件）
        const originalFileLocation = path.normalize(path.join(filePath, originalFileName));

        // 决定最终文件名：不存在同名文件则用原始文件名，否则用UUID生成
        let newFileName: string;
        if (!fs.existsSync(originalFileLocation)) {
            newFileName = originalFileName; // 无同名文件，使用原始文件名
        } else {
            // 存在同名文件，保持原有UUID命名逻辑
            newFileName = `${uuid.v4().replace(/-/g, '')}.${fileExt}`;
        }

        // 文件存储路径
        const fileLocation = path.normalize(path.join(filePath, newFileName));

        // fs 创建文件写入流
        const writeFile = fs.createWriteStream(fileLocation);
        // 写入文件
        writeFile.write(await file.toBuffer());
        // 关闭流
        writeFile.close();

        const fileInfo = {
            url: `${this.config.get('DOMAIN')}${this.config.get('FILE_SERVE_ROOT') || ''}/${folderPath}/${newFileName}`,
            folderPath,
            filePath,
            size: file.size,
            type: file.mimetype,
            location: fileLocation,
            business: business || '',
        };
        return ResultData.ok(fileInfo);
    }

    createFolder(folderPath: string) {
        const filePath = path.join(this.productLocation, `${this.config.get<string>('FILE_LOCATION')}`, folderPath);
        if (!fs.existsSync(filePath)) return ResultData.ok(fs.mkdirSync(filePath, { recursive: true }));
        return ResultData.fail(400, '文件夹已存在');

    }

    findAll(folderPath) {
        console.log('folderPath', folderPath);
        let GetFilePath = this.config.get<string>('FILE_LOCATION');
        if (folderPath) GetFilePath = GetFilePath + '/' + folderPath;
        const filePath = path.join(this.productLocation, GetFilePath);
        const files = fs.readdirSync(filePath);
        /*
         stats.isFile()：如果文件是一个常规文件，则返回 true。
         stats.isDirectory()：如果文件是一个目录，则返回 true。
         stats.isSymbolicLink()：如果文件是一个符号链接（软链接），则返回 true。
         stats.size：文件的大小（以字节为单位）。
         stats.birthtime：文件的创建时间。
         stats.atime：文件的最后访问时间。
         stats.mtime：文件的最后修改时间。
         stats.ctime：文件的最后更改时间（包括修改文件权限）。
         */
        return ResultData.ok(files.map(name => {
            const fPath = filePath + '/' + name;
            const stats = fs.statSync(fPath);
            const isFolder = stats.isDirectory();//是否文件夹
            return {
                id: uuid.v4(),
                fileName: name,
                viewPath: `${this.config.get('DOMAIN')}${this.config.get('FILE_SERVE_ROOT') || ''}${(folderPath || '') + '/' + name}`,
                isFolder,
                fileType: isFolder ? '文件夹' : '文件',
                filePath: GetFilePath + '/' + name,//删除文件用
                folderPath: isFolder ? (folderPath || '') + '/' + name : '',
                suffix: isFolder ? 'dir' : name.split('.').pop(),
                createAt: dayjs(stats.birthtime).format('YYYY-MM-DD HH:mm:ss'),
                updateAt: dayjs(stats.ctime).format('YYYY-MM-DD HH:mm:ss'),
                size: stats.size,
                sizeCase: formatBytes(stats.size),
            };
        }).reverse());
    }

    findOne(id: number) {
        return `This action returns a #${id} oss`;
    }

    update(id: number, updateOssDto: UpdateOssDto) {
        return `This action updates a #${id} oss`;
    }

    remove(folderPath) {
        if (!fs.existsSync(folderPath)) return ResultData.fail(
            400,
            `没有该目录或者文件`,
        );
        const stats = fs.statSync(folderPath);
        const isFolder = stats.isDirectory();//是否文件夹
        if (isFolder) {
            fs.readdirSync(folderPath).forEach((file) => {
                const filePath = path.join(folderPath, file);
                if (fs.lstatSync(filePath).isDirectory()) {
                    this.remove(filePath); // 递归删除子文件夹
                } else {
                    fs.unlinkSync(filePath); // 删除文件
                }
            });
            fs.rmdirSync(folderPath); // 删除空文件夹
        } else {
            fs.unlinkSync(folderPath); // 删除文件
        }
        return ResultData.ok(
            null,
            `删除完成`,
        );
    }
}
